package com.iot.toolbox.service;

import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Base64;
import java.util.regex.Pattern;

@Service
public class DataConversionService {

    private static final Pattern HEX_PATTERN = Pattern.compile("^[0-9A-Fa-f]+$");
    private static final DateTimeFormatter DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    /**
     * 将十六进制字符串转换为ASCII字符串
     */
    public String hexToAscii(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        // 移除空格
        hex = hex.replaceAll("\\s+", "");
        
        // 验证是否为有效的十六进制字符串
        if (!HEX_PATTERN.matcher(hex).matches()) {
            throw new IllegalArgumentException("输入不是有效的十六进制字符串");
        }
        
        // 确保长度为偶数
        if (hex.length() % 2 != 0) {
            hex = "0" + hex;
        }
        
        StringBuilder ascii = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String hexByte = hex.substring(i, i + 2);
            int decimal = Integer.parseInt(hexByte, 16);
            ascii.append((char) decimal);
        }
        
        return ascii.toString();
    }

    /**
     * 将ASCII字符串转换为十六进制字符串
     */
    public String asciiToHex(String ascii) {
        if (ascii == null || ascii.isEmpty()) {
            return "";
        }
        
        StringBuilder hex = new StringBuilder();
        byte[] bytes = ascii.getBytes(StandardCharsets.UTF_8);
        
        for (byte b : bytes) {
            hex.append(String.format("%02X", b));
        }
        
        return hex.toString();
    }

    /**
     * 字符串转大写
     */
    public String toUpperCase(String input) {
        return input == null ? "" : input.toUpperCase();
    }

    /**
     * 字符串转小写
     */
    public String toLowerCase(String input) {
        return input == null ? "" : input.toLowerCase();
    }

    /**
     * 十六进制字节序反转
     */
    public String reverse(String input) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        
        // 清理输入，去除空格
        String hex = input.replaceAll("\\s+", "");
        
        // 验证是否为有效的十六进制字符串
        if (!HEX_PATTERN.matcher(hex).matches()) {
            throw new IllegalArgumentException("输入不是有效的十六进制字符串");
        }
        
        // 按字节反转
        return reverseHexBytes(hex);
    }
    
    /**
     * 十六进制字节序反转（辅助方法）
     */
    private String reverseHexBytes(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        hex = hex.replaceAll("\\s+", "");
        
        if (hex.length() % 2 != 0) {
            hex = "0" + hex;
        }
        
        StringBuilder result = new StringBuilder();
        for (int i = hex.length() - 2; i >= 0; i -= 2) {
            result.append(hex.substring(i, i + 2));
        }
        
        return result.toString();
    }

    /**
     * 16进制报文字节间添加空格
     */
    public String addSpaces(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        hex = hex.replaceAll("\\s+", "");
        
        if (!HEX_PATTERN.matcher(hex).matches()) {
            throw new IllegalArgumentException("输入不是有效的十六进制字符串");
        }
        
        if (hex.length() % 2 != 0) {
            hex = "0" + hex;
        }
        
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            if (i > 0) {
                result.append(" ");
            }
            result.append(hex.substring(i, i + 2));
        }
        
        return result.toString();
    }

    /**
     * 去除空格
     */
    public String removeSpaces(String input) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        
        return input.replaceAll("\\s+", "");
    }

    /**
     * 加33反转（用于电表协议）
     */
    public String add33(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        hex = hex.replaceAll("\\s+", "");
        
        if (!HEX_PATTERN.matcher(hex).matches() || hex.length() % 2 != 0) {
            throw new IllegalArgumentException("输入不是有效的十六进制字符串");
        }
        
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String hexByte = hex.substring(i, i + 2);
            int value = Integer.parseInt(hexByte, 16);
            value = (value + 0x33) & 0xFF;
            result.append(String.format("%02X", value));
        }
        
        // 按字节反转
        return reverseHexBytes(result.toString());
    }

    /**
     * 减33反转（用于电表协议）
     */
    public String subtract33(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        hex = hex.replaceAll("\\s+", "");
        
        if (!HEX_PATTERN.matcher(hex).matches() || hex.length() % 2 != 0) {
            throw new IllegalArgumentException("输入不是有效的十六进制字符串");
        }
        
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < hex.length(); i += 2) {
            String hexByte = hex.substring(i, i + 2);
            int value = Integer.parseInt(hexByte, 16);
            value = (value - 0x33) & 0xFF;
            result.append(String.format("%02X", value));
        }
        
        // 按字节反转
        return reverseHexBytes(result.toString());
    }

    /**
     * 十六进制转二进制
     */
    public String hexToBinary(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        hex = hex.replaceAll("\\s+", "");
        
        if (!HEX_PATTERN.matcher(hex).matches()) {
            throw new IllegalArgumentException("输入不是有效的十六进制字符串");
        }
        
        StringBuilder binary = new StringBuilder();
        for (char c : hex.toCharArray()) {
            int value = Character.digit(c, 16);
            binary.append(String.format("%4s", Integer.toBinaryString(value)).replace(' ', '0'));
        }
        
        return binary.toString();
    }

    /**
     * 二进制转十六进制
     */
    public String binaryToHex(String binary) {
        if (binary == null || binary.isEmpty()) {
            return "";
        }
        
        binary = binary.replaceAll("\\s+", "");
        
        // 验证是否为有效的二进制字符串
        if (!binary.matches("^[01]+$")) {
            throw new IllegalArgumentException("输入不是有效的二进制字符串");
        }
        
        // 补齐到4的倍数
        while (binary.length() % 4 != 0) {
            binary = "0" + binary;
        }
        
        StringBuilder hex = new StringBuilder();
        for (int i = 0; i < binary.length(); i += 4) {
            String fourBits = binary.substring(i, i + 4);
            int decimal = Integer.parseInt(fourBits, 2);
            hex.append(Integer.toHexString(decimal).toUpperCase());
        }
        
        return hex.toString();
    }

    /**
     * 数据清洗 - 去除空格、换行符、tab符等无关字符
     * 注意：Base64数据不进行清洗
     */
    public String cleanData(String input, boolean isBase64) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        
        // 如果是Base64数据，则不进行清洗
        if (isBase64) {
            return input;
        }
        
        // 去除空格、换行符、tab符、回车符等
        return input.replaceAll("[\\s\\r\\n\\t]+", "");
    }

    /**
     * Base64编码（16进制方式）
     */
    public String encodeBase64(String hex) {
        if (hex == null || hex.isEmpty()) {
            return "";
        }
        
        try {
            hex = hex.replaceAll("\\s+", "");
            
            if (!HEX_PATTERN.matcher(hex).matches()) {
                throw new IllegalArgumentException("输入不是有效的十六进制字符串");
            }
            
            if (hex.length() % 2 != 0) {
                hex = "0" + hex;
            }
            
            byte[] bytes = hexStringToBytes(hex);
            return Base64.getEncoder().encodeToString(bytes);
        } catch (Exception e) {
            throw new IllegalArgumentException("Base64编码失败: " + e.getMessage());
        }
    }

    /**
     * Base64解码（16进制方式）
     */
    public String decodeBase64(String input) {
        if (input == null || input.isEmpty()) {
            return "";
        }
        
        try {
            byte[] bytes = Base64.getDecoder().decode(input);
            return bytesToHexString(bytes);
        } catch (Exception e) {
            throw new IllegalArgumentException("Base64解码失败，请检查输入是否为有效的Base64字符串");
        }
    }
    
    /**
     * 十六进制字符串转字节数组
     */
    private byte[] hexStringToBytes(String hex) {
        int length = hex.length();
        byte[] data = new byte[length / 2];
        
        for (int i = 0; i < length; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i + 1), 16));
        }
        
        return data;
    }
    
    /**
     * 字节数组转十六进制字符串
     */
    private String bytesToHexString(byte[] bytes) {
        StringBuilder hex = new StringBuilder();
        for (byte b : bytes) {
            hex.append(String.format("%02X", b & 0xFF));
        }
        return hex.toString();
    }

    /**
     * 当前时间戳转换为日期时间字符串
     */
    public String timestampToDateTime() {
        long timestamp = System.currentTimeMillis();
        LocalDateTime dateTime = LocalDateTime.ofInstant(
            Instant.ofEpochMilli(timestamp), 
            ZoneId.systemDefault()
        );
        
        return String.format("时间戳: %d\n日期时间: %s", 
            timestamp, 
            dateTime.format(DATETIME_FORMATTER)
        );
    }

    /**
     * 时间戳转换为日期时间字符串
     */
    public String timestampToDateTime(String timestampStr) {
        if (timestampStr == null || timestampStr.isEmpty()) {
            return timestampToDateTime(); // 返回当前时间
        }
        
        try {
            long timestamp;
            
            // 尝试解析时间戳
            if (timestampStr.length() == 10) {
                // 10位时间戳（秒）
                timestamp = Long.parseLong(timestampStr) * 1000;
            } else if (timestampStr.length() == 13) {
                // 13位时间戳（毫秒）
                timestamp = Long.parseLong(timestampStr);
            } else {
                throw new IllegalArgumentException("时间戳长度应为10位（秒）或13位（毫秒）");
            }
            
            LocalDateTime dateTime = LocalDateTime.ofInstant(
                Instant.ofEpochMilli(timestamp), 
                ZoneId.systemDefault()
            );
            
            return String.format("时间戳: %d\n日期时间: %s", 
                timestamp, 
                dateTime.format(DATETIME_FORMATTER)
            );
            
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("无效的时间戳格式");
        } catch (Exception e) {
            throw new IllegalArgumentException("时间戳转换失败: " + e.getMessage());
        }
    }

    /**
     * 日期时间字符串转换为时间戳
     */
    public String dateTimeToTimestamp(String dateTimeStr) {
        if (dateTimeStr == null || dateTimeStr.isEmpty()) {
            throw new IllegalArgumentException("请输入日期时间字符串");
        }
        
        try {
            LocalDateTime dateTime;
            
            // 尝试解析完整日期时间格式
            if (dateTimeStr.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
                dateTime = LocalDateTime.parse(dateTimeStr, DATETIME_FORMATTER);
            }
            // 尝试解析仅日期格式
            else if (dateTimeStr.matches("\\d{4}-\\d{2}-\\d{2}")) {
                dateTime = LocalDateTime.parse(dateTimeStr + " 00:00:00", DATETIME_FORMATTER);
            }
            else {
                throw new IllegalArgumentException("日期时间格式错误，支持格式: yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss");
            }
            
            long timestamp = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
            
            return String.format("日期时间: %s\n时间戳(毫秒): %d\n时间戳(秒): %d", 
                dateTimeStr, 
                timestamp, 
                timestamp / 1000
            );
            
        } catch (Exception e) {
            throw new IllegalArgumentException("日期时间格式错误，支持格式: yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss");
        }
    }

    /**
     * 获取当前时间戳和日期时间
     */
    public String getCurrentTimestamp() {
        return timestampToDateTime();
    }
}
